﻿using System;
using System.Xml;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Collections;
using Microsoft.Win32;
using System.IO;
using System.Diagnostics;

namespace EEPClientUpdate
{
    public partial class frmUpdate : Form
    {
        Thread threadupdate = null;
        bool serverstart = false;
        bool finished = false;
        string m_sLastDate = "";    //记录传入的服务端最后更新日期
        public frmUpdate(string sLastDate)
        {
            InitializeComponent();
            m_sLastDate = sLastDate;
        }

        private void frmUpdate_Load(object sender, EventArgs e)
        {
            threadupdate = new Thread(new ThreadStart(UpdatePackage));
            threadupdate.Start();
        }

        private void UpdatePackage()
        {
            try
            {
                //检查主进程并强行关闭,否则不能被更新且出错
                String tempName = "";
                int begpos;
                int endpos;

                foreach (Process thisProc in System.Diagnostics.Process.GetProcesses())
                {
                    tempName = thisProc.ToString();
                    begpos = tempName.IndexOf("(") + 1;
                    endpos = tempName.IndexOf(")");
                    tempName = tempName.Substring(begpos, endpos - begpos);
                    if (tempName.ToLower() == "eepnetflclient")
                    {
                        KillProcess(tempName);
                        break;
                    }
                }

                //取得要更新的文件列表
                string log = "";
                DateTime dtstart = DateTime.Now;
                log += "Update Start at " + dtstart.ToString("G");       //log date
                string tempdirectory = string.Format("{0}\\DownLoadTemp", Application.StartupPath);
                if (!Directory.Exists(tempdirectory))
                {
                    Directory.CreateDirectory(tempdirectory);
                }
                string[] fileupdate = Directory.GetFiles(tempdirectory, "*.*", SearchOption.AllDirectories);
                int filecount = fileupdate.Length;
                log += "\r\ntotal " + filecount.ToString() + " files to Update"; // log file amount
                int filesuccess = 0;
                for (int i = 0; i < filecount; i++)
                {
                    string strfile = fileupdate[i];
                    if (!Directory.Exists(Path.GetDirectoryName(strfile.Replace("\\DownLoadTemp", ""))))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(strfile.Replace("\\DownLoadTemp", "")));
                    }
                    try
                    {
                        File.Copy(strfile, strfile.Replace("\\DownLoadTemp", ""), true);
                        filesuccess++;
                        try
                        {
                            File.Delete(strfile);
                        }
                        catch
                        {

                        }
                    }
                    catch
                    {
                        Thread.Sleep(500);
                        try
                        {
                            File.Copy(strfile, strfile.Replace("\\DownLoadTemp", ""), true);//等500毫秒再试一次
                        }
                        catch (Exception e)
                        {
                            log += "\r\n" + strfile + "\r\n更新失败: " + e.Message;//log error
                        }
                    }

                    lbUpdate.Text = strfile.Substring(strfile.LastIndexOf("\\DownLoadTemp") + 14);
                    int per = 100 * i / filecount;
                    lbprocess.Text = per.ToString() + "%";
                    if (per % 5 == 0)
                    {
                        DateTime dtfinish = DateTime.Now;
                        TimeSpan ts = dtfinish - dtstart;
                        int timetofinish = (int)ts.TotalMilliseconds * (filecount - i - 1) / (i + 1);
                        ts = new TimeSpan(0, 0, 0, 0, timetofinish);
                        lbtime.Text = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00");
                    }
                    progressBarUpdate.Value = per;
                }                
                Directory.Delete(tempdirectory, true);

                //更新服务器最新日期至本地文件

                string fileName = Application.StartupPath + "\\UpdateHistory.xml";
                if (!System.IO.File.Exists(fileName))
                {
                    XmlDocument doc = new XmlDocument();
                    XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
                    doc.AppendChild(dec);
                    XmlElement root = doc.CreateElement("Update");
                    doc.AppendChild(root);
                    XmlNode node = doc.CreateElement("History");
                    XmlElement element1 = doc.CreateElement("Last");
                    element1.InnerText = m_sLastDate;
                    node.AppendChild(element1);
                    root.AppendChild(node);
                    doc.Save(fileName);
                }
                else
                {
                    System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
                    xdoc.Load(fileName);
                    System.Xml.XmlNode xNode = null;
                    System.Xml.XmlElement xElem = null;
                    xNode = xdoc.SelectSingleNode("//Update/History");
                    xElem = (System.Xml.XmlElement)xNode.SelectSingleNode("//Last");
                    if (xElem != null)
                    {
                        xElem.InnerText = m_sLastDate;
                    }
                    xdoc.Save(fileName);
                }


                //打开Server
                Process.Start("EEPNetFLClient.exe");
                serverstart = true;
                log += "\r\n" + filesuccess.ToString() + " 文件更新成功.";
                if (filecount > 0)
                {
                    lbprocess.Text = "100%";
                    progressBarUpdate.Value = 100;
                    lbtime.Text = "00:00";
                    UpdateLog(log);
                }
                else
                {

                }
                finished = true;
                this.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void UpdateLog(string log)
        {
            FileStream fs = new FileStream("PackageUpdate.log", FileMode.OpenOrCreate);
            fs.Close();
            StreamWriter sw = new StreamWriter("PackageUpdate.log",true);
            sw.Write(log);
            sw.Write("\r\n\r\n");
            sw.Close();
            
        }

        private void frmUpdate_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (threadupdate != null && finished != true)
            {
                if (MessageBox.Show("更新未完成,您确定退出吗?",
                    "信息提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning)
                    == DialogResult.OK)
                {
                    threadupdate.Abort();
                    if (!serverstart)
                    {
                        Process.Start("EEPNetFLClient.exe");
                    }
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }

        private void KillProcess(string processName)
        {             
            try
            {
                foreach (Process thisproc in Process.GetProcessesByName(processName))
                {
                    thisproc.Kill();
                }
            }
            catch (Exception Exc)
            {
                MessageBox.Show(Exc.ToString());
            }
        }
    }
}